capture log close 

global y = 19
global input_prioryr_data = <>
global input_current_data = <>
global medicaid_elig_data = <>
global code = <>
global output  = <>
global log  = <>


local date = string(date(c(current_date),"DMY"), "%tdCCYYNNDD")
log using $log/log_${y}_`date'.log, replace


*load prior year data
use "$input_prioryr_data"  , clear

g taxyr = 20$y

format tin primary_tin %12.0g

bysort tin (isprimary filing_status exch_inc): keep if _n ==_N //tin is the primary filer if available. 

g famsize = 1 + (filing_status==2) + n_kids
ren exch_inc exch_income_t1

/*Get Medicaid eligibility threshold. Data is from Brooks et al 2019.*/
merge m:1 state using $medicaid_elig_data, keepusing(y20$y) keep(master matched)
ren y20$y medicaid_limit_t1
drop _m

/*get prior year FPL used for claiming/reconciling PTCs*/	
g state_enum =1	if state == "AL" //Alabama
replace state_enum =2	if state == "AK" //Alaska
replace state_enum =3	if state == "AZ" //Arizona
replace state_enum =4	if state == "AR" //Arkansas
replace state_enum =5	if state == "CA" //California
replace state_enum =6	if state == "CO" //Colorado
replace state_enum =7	if state == "CT" //Connecticut
replace state_enum =8	if state == "DE" //Delaware
replace state_enum =9	if state == "DC" //DC
replace state_enum =10	if state == "FL" //Florida
replace state_enum =11	if state == "GA" //Georgia
replace state_enum =12	if state == "HI" //Hawaii
replace state_enum =13	if state == "ID" //Idaho
replace state_enum =14	if state == "IL" //Illinois
replace state_enum =15	if state == "IN" //Indiana
replace state_enum =16	if state == "IA" //Iowa
replace state_enum =17	if state == "KS" //Kansas
replace state_enum =18	if state == "KY" //Kentucky
replace state_enum =19	if state == "LA" //Louisiana
replace state_enum =20	if state == "ME" //Maine
replace state_enum =21	if state == "MD" //Maryland
replace state_enum =22	if state == "MA" //Massachusetts
replace state_enum =23	if state == "MI" //Michigan
replace state_enum =24	if state == "MN" //Minnesota
replace state_enum =25	if state == "MS" //Mississippi
replace state_enum =26	if state == "MO" //Missouri
replace state_enum =27	if state == "MT" //Montana
replace state_enum =28	if state == "NE" //Nebraska
replace state_enum =29	if state == "NV" //Nevada
replace state_enum =30	if state == "NH" //NewHampshire
replace state_enum =31	if state == "NJ" //NewJersey
replace state_enum =32	if state == "NM" //NewMexico
replace state_enum =33	if state == "NY" //NewYork
replace state_enum =34	if state == "NC" //NorthCarolina
replace state_enum =35	if state == "ND" //NorthDakota
replace state_enum =36	if state == "OH" //Ohio
replace state_enum =37	if state == "OK" //Oklahoma
replace state_enum =38	if state == "OR" //Oregon
replace state_enum =39	if state == "PA" //Pennsylvania
replace state_enum =40	if state == "RI" //RhodeIsland
replace state_enum =41	if state == "SC" //SouthCarolina
replace state_enum =42	if state == "SD" //SouthDakota
replace state_enum =43	if state == "TN" //Tennessee
replace state_enum =44	if state == "TX" //Texas
replace state_enum =45	if state == "UT" //Utah
replace state_enum =46	if state == "VT" //Vermont
replace state_enum =47	if state == "VA" //Virginia
replace state_enum =48	if state == "WA" //Washington
replace state_enum =49	if state == "WV" //WestVirginia
replace state_enum =50	if state == "WI" //Wisconsin
replace state_enum =51	if state == "WY" //Wyoming

ren state state_str
ren state_enum state

*povline and fpl 
do $code/calc_pov_line.do 
ren calc_pov_ln calc_pov_ln_t1

g calcfpl_t1 = round(exch_income_t1/calc_pov_ln_t1, .01) 
replace calcfpl_t1 = 0 if calcfpl_t1<0
g calcfpl_100_t1 = calcfpl_t1*100
ren state* state*_t1
ren famsize famsize_t1
ren filing_status filing_status_t1
ren primary_tin primary_t1
ren isprimary isprimary_t1
drop n_kids taxyr

	
/*merge back with this year's data*/
merge 1:m tin using  $input_current_data  
g has_t1 = _merge==3 //had prior year 
drop _merge 

g taxyr = 20$y

/*Get Medicaid eligibility threshold. Data is from Brooks et al 2019.*/
merge m:1 state using $medicaid_elig_data, keepusing(y20$y) keep(master matched)
ren y20$y medicaid_limit
drop _m

/******************************************************************************
	*Generate hypothetical percent fpls and credits if you are a filer or a nonfiler for current year
*******************************************************************************/
	g state_enum =1	if state == "AL" //Alabama
	replace state_enum =2	if state == "AK" //Alaska
	replace state_enum =3	if state == "AZ" //Arizona
	replace state_enum =4	if state == "AR" //Arkansas
	replace state_enum =5	if state == "CA" //California
	replace state_enum =6	if state == "CO" //Colorado
	replace state_enum =7	if state == "CT" //Connecticut
	replace state_enum =8	if state == "DE" //Delaware
	replace state_enum =9	if state == "DC" //DC
	replace state_enum =10	if state == "FL" //Florida
	replace state_enum =11	if state == "GA" //Georgia
	replace state_enum =12	if state == "HI" //Hawaii
	replace state_enum =13	if state == "ID" //Idaho
	replace state_enum =14	if state == "IL" //Illinois
	replace state_enum =15	if state == "IN" //Indiana
	replace state_enum =16	if state == "IA" //Iowa
	replace state_enum =17	if state == "KS" //Kansas
	replace state_enum =18	if state == "KY" //Kentucky
	replace state_enum =19	if state == "LA" //Louisiana
	replace state_enum =20	if state == "ME" //Maine
	replace state_enum =21	if state == "MD" //Maryland
	replace state_enum =22	if state == "MA" //Massachusetts
	replace state_enum =23	if state == "MI" //Michigan
	replace state_enum =24	if state == "MN" //Minnesota
	replace state_enum =25	if state == "MS" //Mississippi
	replace state_enum =26	if state == "MO" //Missouri
	replace state_enum =27	if state == "MT" //Montana
	replace state_enum =28	if state == "NE" //Nebraska
	replace state_enum =29	if state == "NV" //Nevada
	replace state_enum =30	if state == "NH" //NewHampshire
	replace state_enum =31	if state == "NJ" //NewJersey
	replace state_enum =32	if state == "NM" //NewMexico
	replace state_enum =33	if state == "NY" //NewYork
	replace state_enum =34	if state == "NC" //NorthCarolina
	replace state_enum =35	if state == "ND" //NorthDakota
	replace state_enum =36	if state == "OH" //Ohio
	replace state_enum =37	if state == "OK" //Oklahoma
	replace state_enum =38	if state == "OR" //Oregon
	replace state_enum =39	if state == "PA" //Pennsylvania
	replace state_enum =40	if state == "RI" //RhodeIsland
	replace state_enum =41	if state == "SC" //SouthCarolina
	replace state_enum =42	if state == "SD" //SouthDakota
	replace state_enum =43	if state == "TN" //Tennessee
	replace state_enum =44	if state == "TX" //Texas
	replace state_enum =45	if state == "UT" //Utah
	replace state_enum =46	if state == "VT" //Vermont
	replace state_enum =47	if state == "VA" //Virginia
	replace state_enum =48	if state == "WA" //Washington
	replace state_enum =49	if state == "WV" //WestVirginia
	replace state_enum =50	if state == "WI" //Wisconsin
	replace state_enum =51	if state == "WY" //Wyoming

	ren state state_str
	ren state_enum state
	ren tax_famsize famsize 	

	*povline and fpl
	do $code/calc_pov_line.do 
	ren famsize tax_famsize 
	
	*For filers exch_income is computed from AGI, non tax SS benfits, tax exempt intrest, untaxed foreign income, and agi of dependent filers 
	*For nonfilers exch_income is constructed per (Auten-Splinter 2022) from 1099-R/5498, W2, and 1099-Div/INT/MISC/G(for UI only)
	g calcfpl= round(exch_income/calc_pov_ln, .01) 
	replace calcfpl= 0 if calcfpl<0
	g calcfpl_100 = calcfpl*100
	
	*calculate ptc max using 2019 applicable figures in Rev. Proc. 2018-34

	g payout_max_calcfpl = 1.001
	replace payout_max_calcfpl = .0208 	if calcfpl<1.00 	& calcfpl!=.
	replace payout_max_calcfpl = .0208 	if calcfpl >=1.00	& calcfpl <1.33 & calcfpl!=.
	replace payout_max_calcfpl = .0311  	+ (calcfpl - 1.33)*(.0104/.17) 	if calcfpl >=1.33 	& calcfpl <1.50 & calcfpl!=.
	replace payout_max_calcfpl = .0415  	+ (calcfpl - 1.5) *(.0239/.5) 	if calcfpl >=1.50 	& calcfpl <2.00 & calcfpl!=.
	replace payout_max_calcfpl = .0654  	+ (calcfpl - 2.0) *(.0182/.5) 	if calcfpl >=2.00 	& calcfpl <2.50 & calcfpl!=.
	replace payout_max_calcfpl = .0836 		+ (calcfpl - 2.5) *(.0150/.5) 	if calcfpl >=2.50 	& calcfpl <3.00 & calcfpl!=.
	replace payout_max_calcfpl = .0986 	if calcfpl >=3.00 	& calcfpl <4.00 & calcfpl!=.


	*calculate hypothetical ptc 
	g contrib_amt = payout_max_calcfpl* exch_income if exch_income>0
	replace exch_income = 0 if exch_income==. 
	
	g hyp_ptc = min(prem_1095, max(slcsp_1095 - contrib_amt,0))
	g hyp_aptc_less_ptc = aptc_1095 - hyp_ptc
	g hyp_trueup = 0 
	replace hyp_trueup = -hyp_aptc_less_ptc if hyp_aptc_less_ptc<0
	g hyp_excess = max(hyp_aptc_less_ptc,0)
	g hyp_repay = min(hyp_excess,calc_repaylim) 
	g hyp_unrecap = hyp_excess  - hyp_repay	
		
	local source = "irs"	
	/******************************************************************************
	*Decompose excess PTC>APTC, aka the Trueup. 
	Hypothetical Trueup for folks who appear eligible under our calcuations but did not file and or reconcile are not included, since no payments have been claimed/made. 
	*******************************************************************************/

		g itrueup = ptc_net_8962>0& ptc_net_8962!=. //only decompose trueup if it actually happened. 
		
		/****based on 1095a data and prior year family size*/
		g trueup_reason_1095a = 0 if itrueup //unassigned
		replace trueup_reason_1095a = 1 if trueup_reason_1095a==0 & has_t1==0 //no past record 
		replace trueup_reason_1095a = 2	if trueup_reason_1095a==0 & aptc_1095<exch_cred_8962 & aptc_1095==0	//Did not take APTC
		//other data inconsistency
		replace trueup_reason_1095a = 6 if trueup_reason_1095a==0 & first_state_1095a=="" // no state
		replace trueup_reason_1095a = 7 if trueup_reason_1095a==0 & abs(aptc_1095-aptc_8962)>=50 //aptcs don't match
		replace trueup_reason_1095a = 8 if trueup_reason_1095a==0 & abs(prem_1095-prem_8962)>=50 //Prems don't match
		replace trueup_reason_1095a = 9 if trueup_reason_1095a==0 & abs(slcsp_1095-slcsp_8962)>=50 //SLCSP don't match
		//back to normal reasons
		replace trueup_reason_1095a = 3 	if trueup_reason_1095a==0 & aptc_1095<exch_cred_8962 & /// go from a lower povline state to a higher one --> decreasing your %fpl
			(((first_state_1095a!="HI" & first_state_1095a!="AK") & state_48==0) | (first_state_1095a=="HI" & state_ak==1)) //(move from 48 to ak or hi) OR (move from HI to AK)
		replace trueup_reason_1095a = 4 	if trueup_reason_1095a==0 & aptc_1095<exch_cred_8962 & famsize_t1<tax_famsize //family size grew
		replace trueup_reason_1095a = 5 	if trueup_reason_1095a==0 & aptc_1095<exch_cred_8962 &calcfpl_1095 >calcfpl  //income lower unless missing imputation
		
		label define truereason1095a 0 "Unassigned" 1 "No t-1" 2 "No APTC" 3 "Moved" 4 "Larger Family" 5 "Income Lower" 6 "Missing State info" 7 "Bad APTC Info" 8 "Bad Prems"  9 "Bad SLCP info" 
		label values trueup_reason_1095a truereason1095a

		*Figure 4 D: True-up costs	
		estpost tabstat ptc_net_8962 , by(trueup_reason_1095a) stat(count sum mean sd) columns(statistics)
		esttab . using $output/decomp_trueup_f1095a_`source'_$y.csv, cells("sum(fmt(%12.0g)) mean sd ") nomtitle nonumber  varlabels(`e(labels)') varwidth(20) nodepvar replace
		
		
	/******************************************************************************
	 Decompose excess APTC > PTC. 
	 This decomposes into amounts that are recaptured or not recaptured. Also refered to as repayments and safe harbors, respectively. 
	 Amounts of hypothetical repayments made by non reconcilers that are calculated by the IRS are assumed to be eventually recaptured, but amounts we calculate may not. They and Nonfilers are not asssumed to be eventually recaptured and do not enter in the decomposition.
	 Amounts of hypothetical safe harbors for non reconcilers/nonfilers are included in the safe harbor decompostion since the payments have already been made. 
	*******************************************************************************/

		g comb_aptc = aptc_8962 
		replace comb_aptc = aptc_1095 if comb_aptc==. | comb_aptc==0	// fill in the aptc from 1095 if non reconciler or filer. Needed to calculate the safe harbor decomposition 
		
		g comb_excess_aptc = excess_aptc_8962 //irs calculated value, so may exist for non reconcilers
		replace comb_excess_aptc = hyp_excess if (f8962==.|f8962==0) & (excess_aptc_8962==0|excess_aptc_8962==. ) 
		
		*repayments
		g comb_repay = repay_excess_aptc_8962 //irs calculated value, so may exist for non reconcilers
		replace comb_repay = hyp_repay if (f8962==0|f8962==.) & (repay_excess_aptc_8962==0 |repay_excess_aptc_8962==.) //irs has identified some of the nonreconcilers as needing to pay, but the nonfilers are not included here
		g non_repay = comb_repay - repay_excess_aptc_8962 //non payments that we calculated, that the IRS hasn't identified yet.... 
				
		*safe harbor		
		g comb_excess_unrecap = excess_unrecap_8962
		replace comb_excess_unrecap = hyp_unrecap if (f8962==0|f8962==.) & (excess_unrecap_8962==. | excess_unrecap_8962==0)
	
		g iexcess = comb_excess_aptc>0 & comb_excess_aptc!=.
	

		/*****based on 1095a data and prior year family size*/
		g excess_reason_1095a = 0 if iexcess //unassigned
		replace excess_reason_1095a = 1 if 	excess_reason_1095a==0 & (match_priority==2) //nonfiler
		replace excess_reason_1095a = 2 if 	excess_reason_1095a==0 & (f8962==0 |f8962==.) //didn't file an 8962
		replace excess_reason_1095a = 3 if 	excess_reason_1095a==0 & has_t1==0 //no past record
		replace excess_reason_1095a = 4 if 	excess_reason_1095a==0 & (filing_status==3 | filing_status==6) //MFS repay everything
		//other data inconsistency
		replace excess_reason_1095a = 8 if excess_reason_1095a==0 & first_state_1095a=="" // no state
		replace excess_reason_1095a = 9 if excess_reason_1095a==0 & abs(aptc_1095-aptc_8962)>=50 //aptcs don't match
		replace excess_reason_1095a = 10 if excess_reason_1095a==0 & abs(prem_1095-prem_8962)>=50 & fpl_8962<401  & prem_8962!=0 //Premiums don't match & you weren't over 400 FPL. Lots don't fill in premium/ slcsp. Ignore 0s 
		replace excess_reason_1095a = 11 if excess_reason_1095a==0 & abs(slcsp_1095-slcsp_8962)>=50 & fpl_8962<401 & slcsp_8962!=0 //SLCSP don't match & you weren't over 400FPL.  Lots don't fill in premium/ slcsp if they were are 400+. 
		replace excess_reason_1095a = 12 if excess_reason_1095a==0 & fpl_8962>=400 & comb_excess_unrecap>1 // This shouldn't have anyone. There are some with comb_excess_unrecap>0, but they are 1 and due to rounding in the irs. They don't look like true safe harbors. 
		
		// back to normal reasons
		replace excess_reason_1095a = 5 if 	excess_reason_1095a==0 & aptc_1095>exch_cred_8962 & /// go from a higher povline state to a lower one ---> increase fpl %
			(((first_state_1095a=="HI"|first_state_1095a=="AK") & state_48==1) | (first_state_1095a=="AK" & state_hi==1)) // (move from ak or hi to 48) OR (move from AK to HI)
		replace excess_reason_1095a = 6 if 	excess_reason_1095a==0 & aptc_1095>exch_cred_8962 & famsize_t1>tax_famsize //fam size shrunk
		replace excess_reason_1095a = 7 if 	excess_reason_1095a==0 & aptc_1095>exch_cred_8962 & calcfpl_1095<calcfpl //income higher - imputed this must be the case unless missing imputation
		replace excess_reason_1095a = 7 if 	excess_reason_1095a==0 & aptc_1095>0 & calcfpl>4 //got aptc, and their fpl means they are ineligible. even if we weren't able to impute the percent fpl at signup, we know they must have been lower

		replace excess_reason_1095a = 13 if excess_reason_1095a==0 & calcfpl< max(1.0,medicaid_limit) //got aptc, and their fpl means they are ineligible. even if we weren't able to impute the percent fpl at signup, know it must have been higher

		label define excessreason1095 0 "Unassigned" 1 "Nonfiler" 2 "Not Reconciled" 3 "No t-1" 4 "MFS" 5 "Moved" 6 "Smaller Family" 7 "Income Higher" 8 "No State" 9 "Bad APTC" 10 "Bad Prem" 11 "Bad SCLSP" 12 "Ineligible Safe Harbor" 13 "Medicaid Eligible"
		label values excess_reason_1095a excessreason1095

		*Figure 4 B & C: Repayment costs and Safe-harbor costs
		estpost tabstat  comb_excess_aptc repay_excess_aptc_8962 comb_excess_unrecap non_repay, by(excess_reason_1095a) stat(sum) 
		esttab . using $output/decomp_excess_f1095a_`source'_$y.csv, cells("comb_excess_aptc(fmt(%12.0g)) repay_excess_aptc_8962(fmt(%12.0g)) comb_excess_unrecap(fmt(%12.0g)) non_repay(fmt(%12.0g))") ///
			nomtitle nonumber  nodepvar  varlabels(`e(labels)') varwidth(20)    replace 

capture log close


